#include "AchievementMgr.h"
#include "Common/TableData/AchievementAchievementCfg.h"
#include "Common/TableData/AchievementAchievementrewardCfg.h"
#include "Common/TableData/ConstantConstantCfg.h"
#include "base/core/utility.h"
#include "LogicService.h"

AchievementMgr::AchievementMgr()
{
	_typeAchievementIdMap.clear();
	_typeAchievementRewardIndexMap.clear();
	_openLevel = 0;
}

AchievementMgr::~AchievementMgr()
{

}

bool AchievementMgr::Init()
{
	if (!LoadAchievementCfg())
	{
		return false;
	}

	if (!LoadAchievementRewardCfg())
	{
		return false;
	}

	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}

	pMessageDispatch->registerServerHandler(EMODULE_ID_ACHIEVEMENT, this);

	const ConstantConstantCfgInfo* pConstCfg = g_GetConstantConstantCfgTable()->GetConstantConstantCfgInfo(EArg_OpenAchieveLel);
	_openLevel = (pConstCfg == nullptr) ? 0xff : pConstCfg->constantdata;

	return true;
}

bool AchievementMgr::UnInit()
{
	_typeAchievementIdMap.clear();
	_typeAchievementRewardIndexMap.clear();

	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}
	
	pMessageDispatch->unregisterServerHandler(EMODULE_ID_ACHIEVEMENT);
	return true;
}

bool AchievementMgr::LoadAchievementCfg()
{
	const AchievementAchievementCfgMap *pAchievementCfgMap = g_GetAchievementAchievementCfgTable()->GetAchievementAchievementCfgMap();
	if (!pAchievementCfgMap)
	{
		return false;
	}

	AchievementAchievementCfgMap::const_iterator mapIter = pAchievementCfgMap->begin();
	for (; mapIter != pAchievementCfgMap->end(); mapIter++)
	{
		uint32_t achievementSubType = mapIter->second.achievementSubType;
		uint32_t achievementSubSunType = mapIter->second.achievementSubSunType;
		uint32_t achievementId = mapIter->second.achievementId;
		OEDER_MAP_UINT32_ORDER_MAP_UINT32_VEC_UINT32::iterator iter = _typeAchievementIdMap.find(achievementSubType);
		if (_typeAchievementIdMap.end() == iter)
		{
			ORDER_MAP_UINT32_VEC_UINT32 cfgMap;
			VEC_UINT32 cfgVec;
			cfgVec.push_back(achievementId);
			cfgMap[achievementSubSunType] = cfgVec;
			_typeAchievementIdMap[achievementSubType] = cfgMap;
		}
		else
		{
			ORDER_MAP_UINT32_VEC_UINT32::iterator it = iter->second.find(achievementSubSunType);
			if (iter->second.end() == it)
			{
				iter->second[achievementSubSunType].push_back(achievementId);
			}
			else
			{
				it->second.push_back(achievementId);
			}
		}
	}

	return true;
}

bool AchievementMgr::LoadAchievementRewardCfg()
{
	const AchievementAchievementrewardCfgMap *pAchievementRewardCfgMap = g_GetAchievementAchievementrewardCfgTable()->GetAchievementAchievementrewardCfgMap();
	if (!pAchievementRewardCfgMap)
	{
		return false;
	}

	AchievementAchievementrewardCfgMap::const_iterator mapIter = pAchievementRewardCfgMap->begin();
	for (; mapIter != pAchievementRewardCfgMap->end(); mapIter++)
	{
		uint32_t achievementType = mapIter->second.achievementType;
		uint32_t achievementPointValue = mapIter->second.achievementPointValue;
		OEDER_MAP_UINT32_ORDER_MAP_UINT32_UINT32::iterator iter = _typeAchievementRewardIndexMap.find(achievementType);
		if (_typeAchievementRewardIndexMap.end() == iter)
		{
			ORDER_MAP_UINT32_UINT32 cfgMap;
			cfgMap[achievementPointValue] = 1;
			_typeAchievementRewardIndexMap[achievementType] = cfgMap;
		}
		else
		{
			iter->second[achievementPointValue] = 1;
		}
	}

	return true;
}

void AchievementMgr::onServerMessage(uint32_t actionId, RECV_PACKAGE &package)
{
	switch (actionId)
	{
	case SERVER_INTERNAL_ACHIEVEMENTNOTIFY:
		OnWGAchievementNotify(package);
		break;
	default:
		break;
	}
}

bool AchievementMgr::OnWGAchievementNotify(RECV_PACKAGE &package)
{
	WGAchievementNotify notify;

	if (!notify.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
	{
		MMOLOG_FMT_ERROR("[logic] AchievementMgr::OnWGAchievementNotify WGAchievementNotify parse failed...");
		return false;
	}

	CharIDType charId = notify.charid();
	Player* pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		MMOLOG_FMT_ERROR("[logic] AchievementMgr::OnWGAchievementNotify but Player is nullptr charId:%u", charId);
		return false;
	}

	Part* pIachievement = pPlayer->GetPart(PART_ACHIEVEMENT);
	if (nullptr == pIachievement)
	{
		MMOLOG_FMT_ERROR("[logic] AchievementMgr::OnWGAchievementNotify but pIachievement is nullptr charId:%u", charId);
		return false;
	}

	AchievementParameterInfo achievementParameter;
	achievementParameter.type = notify.type();
	achievementParameter.parameter = notify.parameter();
	achievementParameter.parameterType = notify.parametertype();
	achievementParameter.count = notify.count();

	pIachievement->UpdateAchievement(achievementParameter);

	return true;
}

VEC_UINT32* AchievementMgr::GetAchievementIdVec(AchievementParameterInfo& achievementParameter)
{
	uint32_t parameterType = achievementParameter.parameterType;
	uint32_t parameter = achievementParameter.parameter;
	OEDER_MAP_UINT32_ORDER_MAP_UINT32_VEC_UINT32::iterator iter = _typeAchievementIdMap.find(parameterType);
	if (_typeAchievementIdMap.end() == iter)
	{
		return nullptr;
	}

	ORDER_MAP_UINT32_VEC_UINT32::iterator it = iter->second.find(parameter);
	if (iter->second.end() == it)
	{
		return nullptr;
	}

	return &(it->second);
}

int32_t AchievementMgr::GetAchievementBoxIndex(uint32_t sortType, uint32_t pointValue)
{
	OEDER_MAP_UINT32_ORDER_MAP_UINT32_UINT32::iterator iter = _typeAchievementRewardIndexMap.find(sortType);
	if (_typeAchievementRewardIndexMap.end() == iter)
	{
		return -1;
	}

	int32_t index = -1;
	ORDER_MAP_UINT32_UINT32::iterator it = iter->second.begin();
	for (; it != iter->second.end(); ++it)
	{
		if (pointValue >= it->first)
		{
			index++;
		}
	}

	return index;
}
